const { JJCourse, JJUserOrder, JJUserCourse, Ctcdb, JJCourseRefundRate, JJUser } = require('../../models/ctcdb');
const BaseResp = require('../../utils/baseResp');
const errorCode = require('../../utils/errorCode');
const SequenceUtil = require('../../utils/sequece');

async function buy({ courseId, userId }) {
  // 这里添加一个用户如果没有留联系方式，没法进行购买
  const user = await JJUser.findOne({
    where: {
      id: userId
    },
    raw: true,
    attributes: ['id', 'phone']
  });
  if (!user.phone) {
    throw BaseResp.error(errorCode.COURSE.NOT_PHONE_NOT_BUY)
  }
  const course = await JJCourse.findOne({
    where: {
      id: courseId,
      status: 1
    },
    attributes: ['totalMoney', 'id', 'courseName', 'totalMoney', 'JUserId', 'type', 'isSend', 'signEndTime', 'maxNum'],
    raw: true
  });
  if (!course) {
    throw BaseResp.error(errorCode.COURSE.NOT_FOUND)
  }
  // await
  const { totalMoney, JUserId: lUserId, courseName, type, isSend, signEndTime, maxNum } = course;
  // 不是私教课的话，就需要加一个判断g
  if (type !== 2) {
    if (new Date(signEndTime).getTime() < Date.now()) {
      throw BaseResp.error(errorCode.COURSE.TIME_END)
    }
  }
  if (type === 2) {
    // todo 这里要不要锁定（就是只有一个人能买，下单后没支付会有一段时间的延迟）
    // fixme 有一种方案，一个订单在多少分钟内没支付的话，就算失败
    const selfUserCourse = await JJUserCourse.findOne({
      where: {
        courseId,
        state: 1,
        type: 1
      },
      attributes: ['id'],
      raw: true
    });
    if (selfUserCourse) {
      throw BaseResp.error(errorCode.COURSE.ONLY_CAN_BUY_ONE)
    }
  }
  const count = await JJUserCourse.count({
    where: {
      courseId,
      type: 1,
      state: 1
    },
    raw: true
  });
  // 超过最大人数报名限制
  if (count >= maxNum) {
    throw BaseResp.error(errorCode.COURSE.MAX_NUM_LIMIT)
  }
  // 避免购买多次
  const userCourse = await JJUserCourse.findOne({
    where: {
      courseId,
      jUserId: userId,
      type: 1,
      state: 1
    },
    attributes: ['id'],
    raw: true
  });
  if (userCourse) {
    throw BaseResp.error(errorCode.ORDER.HAS_BUY)
  }
  const wxPayId = await SequenceUtil.getWxPayId();
  const transaction = await Ctcdb.transaction(); // 获取事务、
  try {
    const { id: orderId } = await JJUserOrder.create({
      jUserId: userId,
      price: totalMoney,
      status: 0,
      lUserId,
      courseId,
      tradeNo: wxPayId,
      body: courseName
    }, {
      transaction
    });
    await transaction.commit();
    return {
      orderId
    };
  } catch (e) {
    await transaction.rollback();
    return Promise.reject(e)
  }
}

async function modifyOrder({ orderId }) {
  // 查询待支付的订单
  const order = await JJUserOrder.findOne({
    where: {
      id: orderId,
      status: 0
    },
    attributes: ['id', 'courseId', 'lUserId', 'jUserId'],
    raw: true
  });
  if (!order) {
    throw BaseResp.error(errorCode.ORDER.NOT_FOUND)
  }
  const { jUserId, lUserId, courseId, id } = order;
  const transaction = await Ctcdb.transaction(); // 获取事务、
  try {
    // 创建用户课程
    await JJUserCourse.create({
      jUserId,
      courseId,
      lUserId,
      status: 1
    }, {
      transaction
    });
    // 创建用户订单
    await JJUserOrder.update({
      status: 10
    }, {
      where: {
        id: orderId
      },
      transaction
    });
    await transaction.commit();
  } catch (e) {
    await transaction.rollback();
    return Promise.reject(e)
  }
}

async function queryOrderDetail ({ orderId }) {
  // 查询待支付的订单
  const order = await JJUserOrder.findOne({
    where: {
      id: orderId
    },
    attributes: ['id', 'courseId', 'lUserId', 'jUserId', 'body', 'status', 'price', 'orderNo', 'tradeNo'],
    raw: true
  });
  if (!order) {
    throw BaseResp.error(errorCode.ORDER.NOT_FOUND)
  }
  return order
}

async function getOrderRefundRule() {
  const results = await JJCourseRefundRate.findAll({
    attributes: ['type', 'percent', 'time'],
    raw: true
  });
  return results;
}

module.exports = {
  // 购买课程
  buy,
  // 支付完成修改订单
  modifyOrder,
  // 查询订单信息
  queryOrderDetail,
  // 获取退款规则
  getOrderRefundRule
};
